/****************************************************************************
* Copyright (c) 2023 Qualcomm Technologies International, Ltd
****************************************************************************/
/**
 * \file  mfcc_default_tables.h
 * \ingroup  ml_algos\preproc
 *
 * Header file for Mel frequency Cepstral Coefficient (MFCC) preprocessing
 * containing the default constant tables.
 *
 */

#ifndef MFCC_DEFAULT_TABLES_H
#define MFCC_DEFAULT_TABLES_H

#include <stdfix.h>

/****************************************************************************
Constant Table
*/
/*
 *  This tables provided here are for the following configuration:
 *  sampling_rate: 16000
 *  fft size: 512
 *  number of MelFilterbanks: 32
 *  number of MFCCoefficients: 13
 */

#define DEFAULT_MEL_FILTER_BANKS  32
#define DEFAULT_MEL_FILTER_COEFFS 485
#define DEFAULT_NUM_MFCC 13

/*
 * The 'mel_bank_index' and the 'mel_bank_coeff' table provides a way to capture the information present
 * in a MEL Filterbank. Since the Filterbank is sparse, we only tabulate the information of interest rather
 * than the complete table.
 * 
 * The 'mel_bank_index' table provides the start index and the length of each filter in the filterbank. This
 * means that the size of this table will be twice the number of filters in the filterbank. In the example
 * provided below (Note that we are using C style of array indexing beginning at 0):
 * 1. The first filter begins at index 1 and extends for 5 bins, i.e It is from bin 1 till bin 5.
 * 2. The second filter begins at index 3 and extends for 6 bins, i.e It is from bin 3 till bin 8.
 * 3. The last filter begins at index 213 and extends for 43 bins, i.e. It is from bin 213 till bin 255.
 * 
 * The 'mel_bank_coeff' table provides all the filter coefficients in a contiguous manner. As noted above.
 * 1. The first filter extends for 5 bins, the first five coefficients are for this filter.
 * 2. The second filter extends for 6 bins, the next six coefficients are for this filter.
 * 
 * A simple python script to generate these coefficient using librosa is shown below:
 * 
 * import librosa
 * import numpy as np

 * sr=16000
 * nmels=32
 * n_fft=512

 * py_filter = librosa.filters.mel(sr=sr,n_fft=n_fft,n_mels=nmels)
 * print(py_filter.shape)
 * index = [] # will translate into mel_bank_index table
 * coeff = [] # will translate into mel_bank_coeff table
 * total = 0
 * for i in range(nmels):
 *     temp = py_filter[i,:]
 *     nz = [i for i, e in enumerate(temp) if e != 0]
 *     nzc = [e for i, e in enumerate(temp) if e != 0]
 *     coeff.extend(nzc)
 *     index.append(nz[0])
 *     total += len(nz)
 *     index.append(len(nz))
 */

#pragma datasection const
unsigned default_mel_bank_index[DEFAULT_MEL_FILTER_BANKS << 1] = {
1, 5, 3, 6, 6, 6, 9, 6, 12, 6, 15, 6, 18, 6, 21, 6, 24, 6, 27, 6, 30, 6, 33, 6, 36, 7, 39, 8, 43, 9, 47, 10,
52, 11, 57, 12, 63, 13, 69, 14, 76, 15, 83, 17, 91, 19, 100, 21, 110, 23, 121, 25, 133, 27, 146, 30, 160, 33,
176, 37, 193, 40, 213, 43 };

#pragma datasection const
sat fract default_mel_bank_coeff[DEFAULT_MEL_FILTER_COEFFS] = {
 0.0037403044r,  0.0074806088r,  0.010659648r,   0.006919344r,   0.0031790396r, 0.00028063243r, 0.004020937r,   0.007761241r,
 0.0103790155r,  0.0066387113r,  0.002898407r,   0.00056126487r, 0.004301569r,  0.008041874r,   0.010098384r,   0.006358079r,
 0.0026177748r,  0.0008418973r,  0.0045822016r,  0.008322506r,   0.00981775r,   0.006077447r,   0.0023371421r,  0.0011225297r,
 0.0048628342r,  0.008603138r,   0.0095371185r,  0.005796814r,   0.0020565097r, 0.0014031621r,  0.0051434664r,  0.008883771r,
 0.009256486r,   0.0055161817r,  0.0017758774r,  0.0016837945r,  0.005424099r,  0.009164403r,   0.008975853r,   0.0052355495r,
 0.0014952449r,  0.001964427r,   0.0057047317r,  0.009445035r,   0.0086952215r, 0.004954917r,   0.0012146125r,  0.0022450595r,
 0.005985364r,   0.0097256685r,  0.008414589r,   0.0046742843r,  0.00093398005r,0.0025231163r,  0.006259607r,   0.009996097r,
 0.008131374r,   0.004402496r,   0.00067361805r, 0.0026805282r,  0.0062531694r, 0.009825811r,   0.007774117r,   0.0044823796r,
 0.0011906427r,  0.0024690253r,  0.0054824166r,  0.008495808r,   0.0078353705r, 0.0050930562r,  0.002350743r,   0.0015929389r,
 0.00408856r,    0.006584182r,   0.008399167r,   0.006128046r,   0.0038569253r, 0.0015858043r,  0.00029511747r, 0.0023619337r,
 0.00442875r,    0.0064955666r,  0.0073711514r,  0.005490261r,   0.003609371r,  0.0017284808r,  0.00051650696r, 0.0022281965r,
 0.0039398866r,  0.005651576r,   0.0070983446r,  0.0055406345r,  0.0039829244r, 0.0024252145r,  0.00086750457r, 0.000114867355r,
 0.0015324494r,  0.0029500313r,  0.0043676137r,  0.0057851956r,  0.0060030487r, 0.0047129896r,  0.00342293r,    0.0021328703r,
 0.0008428105r,  0.0005201914r,  0.0016942002r,  0.002868209r,   0.004042218r,  0.005216227r,   0.0056128185r,  0.0045444206r,
 0.003476023r,   0.0024076253r,  0.0013392275r,  0.0002708299r,  0.000337081r,  0.0013093682r,  0.0022816553r,  0.0032539424r,
 0.0042262296r,  0.005198517r,   0.004784456r,   0.0038996337r,  0.003014811r,  0.0021299887r,  0.0012451663r,  0.00036034393r,
 0.0006011078r,  0.0014063336r,  0.0022115596r,  0.0030167853r,  0.0038220112r, 0.004627237r,   0.004520804r,   0.0037880144r,
 0.0030552251r,  0.0023224354r,  0.0015896459r,  0.00085685623r, 0.00012406668r,0.00039528692r, 0.0010621564r,  0.001729026r,
 0.0023958955r,  0.0030627649r,  0.0037296345r,  0.0043965043r,  0.0040052794r, 0.0033984003r,  0.0027915207r,  0.0021846413r,
 0.0015777617r,  0.00097088225r, 0.0003640028r,  0.00045877992r, 0.0010110659r, 0.001563352r,   0.002115638r,   0.002667924r,
 0.0032202099r,  0.0037724958r,  0.003902609r,   0.0034000054r,  0.0028974018r, 0.002394798r,   0.0018921945r,  0.0013895908r,
 0.0008869872r,  0.00038438357r, 0.00018305036r, 0.0006404409r,  0.0010978314r, 0.0015552221r,  0.0020126128r,  0.0024700032r,
 0.0029273937r,  0.0033847843r,  0.0036366824r,  0.0032204378r,  0.002804193r,  0.0023879483r,  0.0019717035r,  0.0015554586r,
 0.0011392139r,  0.0007229691r,  0.00030672437r, 0.00008909963r, 0.00046789998r,0.00084670034r, 0.0012255007r,  0.0016043009r,
 0.0019831012r,  0.0023619018r,  0.0027407021r,  0.0031195024r,  0.0033079323r, 0.002963208r,   0.0026184837r,  0.0022737593r,
 0.0019290348r,  0.0015843107r,  0.0012395862r,  0.0008948619r,  0.00055013754r,0.00020541322r, 0.0000825429r,  0.00039625663r,
 0.00070997037r, 0.0010236842r,  0.0013373978r,  0.0016511116r,  0.0019648254r, 0.0022785391r,  0.0025922528r,  0.0029059665r,
 0.002977527r,   0.0026920342r,  0.0024065415r,  0.0021210487r,  0.0018355558r, 0.0015500631r,  0.0012645703r,  0.0009790775r,
 0.0006935848r,  0.00040809202r, 0.00012259925r, 0.000104995466r,0.00036480598r,0.00062461646r, 0.00088442693r, 0.0011442375r,
 0.001404048r,   0.0016638585r,  0.001923669r,   0.0021834795r,  0.00244329r,   0.0027031004r,  0.0026797664r,  0.0024433278r,
 0.0022068892r,  0.0019704506r,  0.0017340122r,  0.0014975736r,  0.001261135r,  0.0010246965r,  0.0007882579r,  0.00055181934r,
 0.00031538084r, 0.00007894229r, 0.00012276895r, 0.00033793805r, 0.0005531071r, 0.0007682762r,  0.0009834453r,  0.0011986144r,
 0.0014137834r,  0.0016289526r,  0.0018441216r,  0.0020592907r,  0.0022744597r, 0.0024896287r,  0.0024310348r,  0.002235222r,
 0.002039409r,   0.0018435959r,  0.0016477831r,  0.00145197r,    0.0012561571r, 0.001060344r,   0.00086453115r, 0.0006687182r,
 0.0004729052r,  0.00027709224r, 0.00008127927r, 0.00011870117r, 0.00029689926r,0.00047509733r, 0.0006532954r,  0.00083149347r,
 0.0010096916r,  0.0011878896r,  0.0013660878r,  0.0015442859r,  0.0017224839r, 0.0019006821r,  0.00207888r,    0.0022570782r,
 0.0022361916r,  0.0020740237r,  0.001911856r,   0.0017496882r,  0.0015875204r, 0.0014253525r,  0.0012631847r,  0.001101017r,
 0.00093884923r, 0.0007766814r,  0.00061451364r, 0.00045234582r, 0.00029017805r,0.00012801024r, 0.000086321306r,0.00023390086r,
 0.00038148044r, 0.00052905997r, 0.00067663955r, 0.0008242191r,  0.0009717986r, 0.0011193783r,  0.0012669577r,  0.0014145373r,
 0.0015621168r,  0.0017096964r,  0.001857276r,   0.0020048555r,  0.0020930618r, 0.001958758r,   0.0018244544r,  0.0016901508r,
 0.0015558472r,  0.0014215435r,  0.00128724r,    0.0011529364r,  0.0010186327r, 0.00088432897r, 0.0007500254r,  0.00061572174r,
 0.0004814181r,  0.00034711446r, 0.00021281082r, 0.000078507175r,0.00002574373r,0.00014796574r, 0.00027018774r, 0.0003924097r,
 0.00051463174r, 0.0006368537r,  0.0007590757r,  0.0008812977r,  0.0010035196r, 0.0011257416r,  0.0012479636r,  0.0013701856r,
 0.0014924078r,  0.0016146298r,  0.0017368516r,  0.0018590736r,  0.0018843092r, 0.001773082r,   0.0016618548r,  0.0015506275r,
 0.0014394005r,  0.0013281732r,  0.001216946r,   0.0011057188r,  0.0009944916r, 0.00088326447r, 0.0007720373r,  0.0006608101r,
 0.0005495829r,  0.00043835572r, 0.00032712854r, 0.00021590137r, 0.00010467418r,0.00004205246r, 0.00014327391r, 0.00024449534r,
 0.0003457168r,  0.0004469382r,  0.00054815965r, 0.00064938114r, 0.0007506026r, 0.000851824r,   0.00095304544r, 0.0010542669r,
 0.0011554883r,  0.0012567098r,  0.0013579312r,  0.0014591527r,  0.0015603742r, 0.0016615957r,  0.0017514265r,  0.0016593107r,
 0.0015671948r,  0.0014750791r,  0.0013829633r,  0.0012908474r,  0.0011987317r, 0.0011066159r,  0.0010145r,     0.00092238426r,0.0008302685r,
 0.0007381527r,  0.0006460369r,  0.0005539211r,  0.00046180532r, 0.0003696895r, 0.0002775737r,  0.0001854579r,  0.0000933421r,
 0.000001226312r,0.00000493885r, 0.000088768116r,0.0001725974r,  0.00025642666r,0.00034025594r, 0.00042408518r, 0.00050791446r,
 0.0005917438r,  0.000675573r,   0.0007594023r,  0.00084323157r, 0.0009270609r, 0.0010108901r,  0.0010947194r,  0.0011785487r, 0.001262378r,
 0.0013462072r,  0.0014300365r,  0.0015138658r,  0.001597695r,   0.0015235385r, 0.0014472503r,  0.0013709621r,  0.0012946739r, 0.0012183858r,
 0.0011420975r,  0.0010658094r,  0.0009895212r,  0.000913233r,   0.00083694473r,0.0007606566r,  0.0006843684r,  0.00060808024r,0.00053179206r,
 0.00045550385r, 0.00037921566r, 0.00030292748r, 0.00022663928r, 0.00015035112r,0.000074062926r,0.000068501235r,0.0001379267r,
 0.00020735219r, 0.00027677766r, 0.00034620316r, 0.0004156286r,  0.00048505407r,0.00055447954r, 0.00062390504r, 0.00069333054r,
 0.000762756r,   0.00083218154r, 0.0009016069r,  0.00097103236r, 0.0010404579r, 0.0011098833r,  0.0011793089r,  0.0012487343r, 0.0013181599r,
 0.0013875853r,  0.0014531428r,  0.0013899626r,  0.0013267825r,  0.0012636024r, 0.0012004223r,  0.0011372421r,  0.0010740621r, 0.001010882r,
 0.0009477018r,  0.00088452164r, 0.0008213415r,  0.0007581614r,  0.0006949813r, 0.0006318012r,  0.00056862104r, 0.000505441r,  0.00044226082r,
 0.0003790807r,  0.0003159006r,  0.0002527205r,  0.00018954035r, 0.00012636025r,0.00006318012r
};

/* The dct_table is used to compute Type-II DCT with ortho norm.
 * The formulae for computing is: Y_k = 2 * scale * sum(X_n * cos(pi * k * (2n+1)/2N)) for
 * n=0 till N-1.
 * k=0 till K-1.
 * where:
 * scale = sqrt(1/4N) for k=0
 *         sqrt(1/2N) otherwise
 * 
 * For MFCC, since DCT is taken on the log Mel Spectrogram and the result gives us
 * MFCCoefficients, N here translates into the number of mel filterbanks and K translates
 * into the number of required MFC Coeffients.
 * In this implementation, the DCT table stores scale * (cos(pi * k * (2n+1)/2N)).
 * where N = total number of Mel Bands
 *       K = Number of MFCC Coefficients.
 * This makes the size of the DCT Table as [#MFCC_COEFFICIENTS * #MEL_BANDS]
 * 
 * A simple python script to generate the filter coefficients might look like this:
 * 
 * N = 32
 * K = 13
 * n = np.linspace(0,N-1,N)
 * dct_filter = np.zeros((K,N), dtype=np.float32)
 * for k in range(K):
       tmp = (np.cos(np.pi * k * ((2*n)+1)/(2*N)))
       scale = 1/np.sqrt(2*N)
       if k == 0:
           scale = 1/np.sqrt(4*N)
       dct_filter[k] = tmp * scale
 * #Flatten the array
 * dct_filter = dct_filter.flatten()
 */

#pragma datasection const
sat fract default_dct_table[DEFAULT_NUM_MFCC * DEFAULT_MEL_FILTER_BANKS] = {
  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,
  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,
  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,
  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,
  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,  0.08838835r,
  0.08838835r,  0.08838835r,  0.12484943r,  0.12364706r,  0.12125391r,  0.11769301r,
  0.11299866r,  0.10721608r,  0.10040094r,  0.09261889r,  0.08394487r,  0.07446241r,
  0.06426284r,  0.05344439r,  0.04211123r,  0.03037252r,  0.01834131r,  0.00613346r,
 -0.00613346r, -0.01834131r, -0.03037252r, -0.04211123r, -0.05344439r, -0.06426284r,
 -0.07446241r, -0.08394487r, -0.09261889r, -0.10040094r, -0.10721608r, -0.11299866r,
 -0.11769301r, -0.12125391r, -0.12364706r, -0.12484943r,  0.12439809r,  0.11961754r,
  0.11024016r,  0.0966263r,   0.07929916r,  0.05892459r,  0.03628558r,  0.01225214r,
 -0.01225214r, -0.03628558r, -0.05892459r, -0.07929916r, -0.0966263r,  -0.11024016r,
 -0.11961754r, -0.12439809r, -0.12439809r, -0.11961754r, -0.11024016r, -0.0966263r,
 -0.07929916r, -0.05892459r, -0.03628558r, -0.01225214r,  0.01225214r,  0.03628558r,
  0.05892459r,  0.07929916r,  0.0966263r,   0.11024016r,  0.11961754r,  0.12439809r,
  0.12364706r,  0.11299866r,  0.09261889r,  0.06426284r,  0.03037252r, -0.00613346r,
 -0.04211123r, -0.07446241r, -0.10040094r, -0.11769301r, -0.12484943r, -0.12125391r,
 -0.10721608r, -0.08394487r, -0.05344439r, -0.01834131r,  0.01834131r,  0.05344439r,
  0.08394487r,  0.10721608r,  0.12125391r,  0.12484943r,  0.11769301r,  0.10040094r,
  0.07446241r,  0.04211123r,  0.00613346r, -0.03037252r, -0.06426284r, -0.09261889r,
 -0.11299866r, -0.12364706r,  0.12259816r,  0.1039337r,   0.06944628r,  0.02438629r,
 -0.02438629r, -0.06944628r, -0.1039337r,  -0.12259816r, -0.12259816r, -0.1039337r,
 -0.06944628r, -0.02438629r,  0.02438629r,  0.06944628r,  0.1039337r,   0.12259816r,
  0.12259816r,  0.1039337r,   0.06944628r,  0.02438629r, -0.02438629r, -0.06944628r,
 -0.1039337r,  -0.12259816r, -0.12259816r, -0.1039337r,  -0.06944628r, -0.02438629r,
  0.02438629r,  0.06944628r,  0.1039337r,   0.12259816r,  0.12125391r,  0.09261889r,
  0.04211123r, -0.01834131r, -0.07446241r, -0.11299866r, -0.12484943r, -0.10721608r,
 -0.06426284r, -0.00613346r,  0.05344439r,  0.10040094r,  0.12364706r,  0.11769301r,
  0.08394487r,  0.03037252r, -0.03037252r, -0.08394487r, -0.11769301r, -0.12364706r,
 -0.10040094r, -0.05344439r,  0.00613346r,  0.06426284r,  0.10721608r,  0.12484943r,
  0.11299866r,  0.07446241r,  0.01834131r, -0.04211123r, -0.09261889r, -0.12125391r,
  0.11961754r,  0.07929916r,  0.01225214r, -0.05892459r, -0.11024016r, -0.12439809r,
 -0.0966263r,  -0.03628558r,  0.03628558r,  0.0966263r,   0.12439809r,  0.11024016r,
  0.05892459r, -0.01225214r, -0.07929916r, -0.11961754r, -0.11961754r, -0.07929916r,
 -0.01225214r,  0.05892459r,  0.11024016r,  0.12439809r,  0.0966263r,   0.03628558r,
 -0.03628558r, -0.0966263r,  -0.12439809r, -0.11024016r, -0.05892459r,  0.01225214r,
  0.07929916r,  0.11961754r,  0.11769301r,  0.06426284r, -0.01834131r, -0.09261889r,
 -0.12484943r, -0.10040094r, -0.03037252r,  0.05344439r,  0.11299866r,  0.12125391r,
  0.07446241r, -0.00613346r, -0.08394487r, -0.12364706r, -0.10721608r, -0.04211123r,
  0.04211123r,  0.10721608r,  0.12364706r,  0.08394487r,  0.00613346r, -0.07446241r,
 -0.12125391r, -0.11299866r, -0.05344439r,  0.03037252r,  0.10040094r,  0.12484943r,
  0.09261889r,  0.01834131r, -0.06426284r, -0.11769301r,  0.11548494r,  0.04783543r,
 -0.04783543r, -0.11548494r, -0.11548494r, -0.04783543r,  0.04783543r,  0.11548494r,
  0.11548494r,  0.04783543r, -0.04783543r, -0.11548494r, -0.11548494r, -0.04783543r,
  0.04783543r,  0.11548494r,  0.11548494r,  0.04783543r, -0.04783543r, -0.11548494r,
 -0.11548494r, -0.04783543r,  0.04783543r,  0.11548494r,  0.11548494r,  0.04783543r,
 -0.04783543r, -0.11548494r, -0.11548494r, -0.04783543r,  0.04783543r,  0.11548494r,
  0.11299866r,  0.03037252r, -0.07446241r, -0.12484943r, -0.08394487r,  0.01834131r,
  0.10721608r,  0.11769301r,  0.04211123r, -0.06426284r, -0.12364706r, -0.09261889r,
  0.00613346r,  0.10040094r,  0.12125391r,  0.05344439r, -0.05344439r, -0.12125391r,
 -0.10040094r, -0.00613346r,  0.09261889r,  0.12364706r,  0.06426284r, -0.04211123r,
 -0.11769301r, -0.10721608r, -0.01834131r,  0.08394487r,  0.12484943r,  0.07446241r,
 -0.03037252r, -0.11299866r,  0.11024016r,  0.01225214r, -0.0966263r,  -0.11961754r,
 -0.03628558r,  0.07929916r,  0.12439809r,  0.05892459r, -0.05892459r, -0.12439809r,
 -0.07929916r,  0.03628558r,  0.11961754r,  0.0966263r,  -0.01225214r, -0.11024016r,
 -0.11024016r, -0.01225214r,  0.0966263r,   0.11961754r,  0.03628558r, -0.07929916r,
 -0.12439809r, -0.05892459r,  0.05892459r,  0.12439809r,  0.07929916r, -0.03628558r,
 -0.11961754r, -0.0966263r,   0.01225214r,  0.11024016r,  0.10721608r, -0.00613346r,
 -0.11299866r, -0.10040094r,  0.01834131r,  0.11769301r,  0.09261889r, -0.03037252r,
 -0.12125391r, -0.08394487r,  0.04211123r,  0.12364706r,  0.07446241r, -0.05344439r,
 -0.12484943r, -0.06426284r,  0.06426284r,  0.12484943r,  0.05344439r, -0.07446241r,
 -0.12364706r, -0.04211123r,  0.08394487r,  0.12125391r,  0.03037252r, -0.09261889r,
 -0.11769301r, -0.01834131r,  0.10040094r,  0.11299866r,  0.00613346r, -0.10721608r,
  0.1039337r,  -0.02438629r, -0.12259816r, -0.06944628r,  0.06944628r,  0.12259816r,
  0.02438629r, -0.1039337r,  -0.1039337r,   0.02438629r,  0.12259816r,  0.06944628r,
 -0.06944628r, -0.12259816r, -0.02438629r,  0.1039337r,   0.1039337r,  -0.02438629r,
 -0.12259816r, -0.06944628r,  0.06944628r,  0.12259816r,  0.02438629r, -0.1039337r,
 -0.1039337r,   0.02438629r,  0.12259816r,  0.06944628r, -0.06944628r, -0.12259816r,
 -0.02438629r,  0.1039337r};

#endif /* MFCC_DEFAULT_TABLES_H */